//
//  View++.swift
//  chat
//
//  Created by 1 on 2023/3/29.
//

import SwiftUI

struct CornerRadiusStyle: ViewModifier {
    var radius: CGFloat
    var corners: UIRectCorner

    struct CornerRadiusShape: Shape {

        var radius = CGFloat.infinity
        var corners = UIRectCorner.allCorners

        func path(in rect: CGRect) -> Path {
            let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
            return Path(path.cgPath)
        }
    }

    func body(content: Content) -> some View {
        content
            .clipShape(CornerRadiusShape(radius: radius, corners: corners))
    }
}

extension View {
    func cornerRadius(radius: CGFloat, corners: UIRectCorner) -> some View {
        ModifiedContent(content: self, modifier: CornerRadiusStyle(radius: radius, corners: corners))
    }
}


///TextEditor
extension View {
/// Layers the given views behind this ``TextEditor``.
    func textEditorBackground<V>(@ViewBuilder _ content: () -> V) -> some View where V : View {
        self
            .onAppear {
                UITextView.appearance().backgroundColor = .clear
            }
            .background(content())
    }
}


// 增强View：隐藏键盘
extension View {
    func hideKeyboard() {
        UIApplication.shared.sendAction(
            #selector(UIResponder.resignFirstResponder),
            to: nil,
            from: nil,
            for: nil
        )
    }
}

extension View {
    func mainGradientTitle() -> some View {
        self.modifier(QSMainGradientTitle())
    }
}

extension View {
    func asImage() -> UIImage {
        let controller = UIHostingController(rootView: self)
        let view = controller.view
        let format = UIGraphicsImageRendererFormat()
        format.scale = 2
        format.opaque = true
        let targetSize = controller.view.intrinsicContentSize
        view?.bounds = CGRect(origin: .zero, size: targetSize)
        view?.backgroundColor = .clear
        let window = UIWindow(frame: view!.bounds)
        window.addSubview(controller.view)
        window.makeKeyAndVisible()
        let renderer = UIGraphicsImageRenderer(bounds: view!.bounds, format: format)
        return renderer.image { rendererContext in
                view?.layer.render(in: rendererContext.cgContext)
        }
    }
}

extension View {
    func saveToPhotoAlbum() {
        let image = self.asImage()
        image.saveToPhotoAlbum()
    }
}



//后退手势
struct EdgeSwipeGesture: ViewModifier {
    @Binding var isShowingBack: Bool
    @GestureState private var dragState = DragState.inactive
    
    enum DragState {
        case inactive
        case dragging(translation: CGSize)
        
        var translation: CGSize {
            switch self {
            case .inactive, .dragging(translation: .zero):
                return .zero
            case .dragging(let translation):
                return translation
            }
        }
        
        var isDragging: Bool {
            switch self {
            case .inactive:
                return false
            case .dragging:
                return true
            }
        }
    }
    func body(content: Content) -> some View {
        content
            .gesture(
                DragGesture()
                    .updating($dragState) { value, state, _ in
                        state = .dragging(translation: value.translation)
                    }
                    .onEnded { value in
                        let dragThreshold: CGFloat = 100
                        if value.translation.width > dragThreshold {
                            withAnimation {
                                self.isShowingBack = true
                            }
                        } else {
                            withAnimation {
                                self.isShowingBack = false
                            }
                        }
                    }
            )
    }
}

extension View {
    func edgeSwipeGesture(isShowingBack: Binding<Bool>) -> some View {
        self.modifier(EdgeSwipeGesture(isShowingBack: isShowingBack))
    }
}
